package com.chinatechstar.component.commons.utils;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

/**
 * 递归列表工具类
 *
 * @author Rei
 */
public class RecursiveListUtils {
    private static final String INIT_PARENT = "parentId";
    private static final String INIT_ID = "id";
    private static String PARENT_ID = "parentId";
    private static String ID_STR = "id";
    private static List<LinkedHashMap<String, Object>> totalList;

    private RecursiveListUtils() {

    }

    private static List<LinkedHashMap<String, Object>> getTotalList() {
        return totalList;
    }

    private static void setTotalList(List<LinkedHashMap<String, Object>> totalList) {
        RecursiveListUtils.totalList = totalList;
    }

    /**
     * 获取根节点列表
     *
     * @param totalList 原始列表
     * @return List<LinkedHashMap < String, Object>>
     */
    public static List<LinkedHashMap<String, Object>> queryRecursiveList(List<LinkedHashMap<String, Object>> totalList) {
        setInitParams(totalList);
        List<LinkedHashMap<String, Object>> resultList = new ArrayList<>();
        List<LinkedHashMap<String, Object>> parentTotalList = totalList.stream().filter(map -> Long.parseLong(String.valueOf(map.get(PARENT_ID))) == 0L)
                .collect(Collectors.toList());

        return getLinkedHashMaps(resultList, parentTotalList);
    }

    /**
     * 获取根节点列表
     *
     * @param totalList     原始列表
     * @param idField       自定义ID字段名
     * @param parentIdField 自定义父ID字段名
     * @return List<LinkedHashMap < String, Object>>
     */
    public static List<LinkedHashMap<String, Object>> queryRecursiveList(List<LinkedHashMap<String, Object>> totalList, String idField, String parentIdField) {
        PARENT_ID = parentIdField;
        ID_STR = idField;
        setTotalList(totalList);
        List<LinkedHashMap<String, Object>> resultList = new ArrayList<>();
        List<LinkedHashMap<String, Object>> parentTotalList = totalList.stream().filter(map -> map.get(PARENT_ID) == null)
                .collect(Collectors.toList());

        return getLinkedHashMaps(resultList, parentTotalList);
    }

    /**
     * 获取根节点列表
     *
     * @param totalList     原始列表
     * @param idField       自定义ID字段名
     * @param parentIdField 自定义父ID字段名
     * @param rootVal       自定义根节点值
     * @return List<LinkedHashMap < String, Object>>
     */
    public static List<LinkedHashMap<String, Object>> queryRecursiveList(List<LinkedHashMap<String, Object>> totalList, String idField, String parentIdField, String rootVal) {
        PARENT_ID = parentIdField;
        ID_STR = idField;
        setTotalList(totalList);
        List<LinkedHashMap<String, Object>> resultList = new ArrayList<>();
        List<LinkedHashMap<String, Object>> parentTotalList = totalList.stream().filter(map -> String.valueOf(map.get(PARENT_ID)).equals(rootVal))
                .collect(Collectors.toList());

        return getLinkedHashMaps(resultList, parentTotalList);
    }

    /**
     * 根据ID获取递归子列表
     *
     * @param id 列表ID
     * @return List<LinkedHashMap < String, Object>>
     */
    private static List<LinkedHashMap<String, Object>> queryRecursiveChildrenList(String id) {
        List<LinkedHashMap<String, Object>> resultList = new ArrayList<>();
        List<LinkedHashMap<String, Object>> childrenTotalList = getTotalList().stream().filter(map -> id.equals(String.valueOf(map.get(PARENT_ID))))
                .collect(Collectors.toList());
        return getLinkedHashMaps(resultList, childrenTotalList);
    }

    /**
     * 获取菜单的根节点列表
     *
     * @param totalList 原始列表
     * @return List<LinkedHashMap < String, Object>>
     */
    public static List<LinkedHashMap<String, Object>> queryMenuRecursiveList(List<LinkedHashMap<String, Object>> totalList) {
        setInitParams(totalList);
        List<LinkedHashMap<String, Object>> resultList = new ArrayList<>();
        List<LinkedHashMap<String, Object>> parentTotalList = totalList.stream().filter(map -> Long.parseLong(String.valueOf(map.get(PARENT_ID))) == 0L)
                .collect(Collectors.toList());
        for (LinkedHashMap<String, Object> stringObjectLinkedHashMap : parentTotalList) {
            LinkedHashMap<String, Object> map = new LinkedHashMap<>();
            for (Entry<String, Object> entry : stringObjectLinkedHashMap.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (key.equals(ID_STR)) {
                    List<LinkedHashMap<String, Object>> data = queryMenuRecursiveChildrenList(String.valueOf(value));
                    if (!data.isEmpty()) {
                        map.put("routes", data);
                    }
                }
                map.put(key, value);
            }
            resultList.add(map);
        }
        return resultList;
    }

    /**
     * 根据ID获取菜单的递归子列表
     *
     * @param id 列表ID
     * @return List<LinkedHashMap < String, Object>>
     */
    private static List<LinkedHashMap<String, Object>> queryMenuRecursiveChildrenList(String id) { // NOSONAR
        List<LinkedHashMap<String, Object>> resultList = new ArrayList<>();
        List<LinkedHashMap<String, Object>> childrenTotalList = getTotalList().stream().filter(map -> id.equals(String.valueOf(map.get(PARENT_ID))))
                .collect(Collectors.toList());
        String pathStr = "path";
        for (LinkedHashMap<String, Object> stringObjectLinkedHashMap : childrenTotalList) {
            LinkedHashMap<String, Object> map = new LinkedHashMap<>();
            for (Entry<String, Object> entry : stringObjectLinkedHashMap.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (key.equals(ID_STR)) {
                    List<LinkedHashMap<String, Object>> data = queryMenuRecursiveChildrenList(String.valueOf(value));
                    if (!data.isEmpty()) {
                        map.put("routes", data);
                    } else {
                        map.put("exact", true);
                    }
                }
                if (key.equals(pathStr) && (String.valueOf(value).contains("http"))) {
                    map.put("target", "_blank");
                }
                map.put(key, value);
            }
            resultList.add(map);
        }
        return resultList;
    }

    /**
     * 获取菜单和按钮的根节点列表
     *
     * @param totalList 原始列表
     * @return List<LinkedHashMap < String, Object>>
     */
    public static List<LinkedHashMap<String, Object>> queryMenuButtonRecursiveList(List<LinkedHashMap<String, Object>> totalList,
                                                                                   Map<String, String> menuButtonMap, Map<String, String> buttonDictMap) {
        setInitParams(totalList);
        List<LinkedHashMap<String, Object>> resultList = new ArrayList<>();
        List<LinkedHashMap<String, Object>> parentTotalList = totalList.stream().filter(map -> Long.parseLong(String.valueOf(map.get(PARENT_ID))) == 0L)
                .collect(Collectors.toList());
        for (LinkedHashMap<String, Object> stringObjectLinkedHashMap : parentTotalList) {
            LinkedHashMap<String, Object> map = new LinkedHashMap<>();
            for (Entry<String, Object> entry : stringObjectLinkedHashMap.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (key.equals(ID_STR)) {
                    List<LinkedHashMap<String, Object>> data = queryMenuButtonRecursiveChildrenList(String.valueOf(value), menuButtonMap, buttonDictMap);
                    if (!data.isEmpty()) {
                        map.put("children", data);
                    }
                }
                map.put(key, value);
            }
            resultList.add(map);
        }
        return resultList;
    }

    /**
     * 根据ID获取菜单和按钮的递归子列表
     *
     * @param id 列表ID
     * @return List<LinkedHashMap < String, Object>>
     */
    private static List<LinkedHashMap<String, Object>> queryMenuButtonRecursiveChildrenList(String id, Map<String, String> menuButtonMap,
                                                                                            Map<String, String> buttonDictMap) {
        List<LinkedHashMap<String, Object>> resultList = new ArrayList<>();
        List<LinkedHashMap<String, Object>> childrenTotalList = getTotalList().stream().filter(map -> id.equals(String.valueOf(map.get(PARENT_ID))))
                .collect(Collectors.toList());
        String menuCodeStr = "menuCode";
        for (LinkedHashMap<String, Object> stringObjectLinkedHashMap : childrenTotalList) {
            LinkedHashMap<String, Object> map = new LinkedHashMap<>();
            String menuCode = null;
            for (Entry<String, Object> entry : stringObjectLinkedHashMap.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (key.equals(menuCodeStr)) {
                    menuCode = value.toString();
                }
                if (key.equals(ID_STR)) {
                    List<LinkedHashMap<String, Object>> data = queryMenuButtonRecursiveChildrenList(String.valueOf(value), menuButtonMap, buttonDictMap);
                    if (!data.isEmpty()) {
                        map.put("children", data);
                    } else {
                        List<LinkedHashMap<String, Object>> buttonData = new ArrayList<>();

                        if (menuButtonMap.get(menuCode) != null) {
                            String[] buttonArray = menuButtonMap.get(menuCode).split(",");
                            for (String s : buttonArray) {
                                LinkedHashMap<String, Object> buttonMap = new LinkedHashMap<>();
                                buttonMap.put("key", menuCode + ":" + s);
                                buttonMap.put("title", buttonDictMap.get(s));
                                buttonData.add(buttonMap);
                            }
                        }

                        map.put("children", buttonData);
                    }
                }
                map.put(key, value);
            }
            resultList.add(map);
        }
        return resultList;
    }

    /**
     * 获取递归数据
     *
     * @param resultList      结果列表
     * @param parentTotalList 父级列表
     * @return List<LinkedHashMap < String, Object>>
     */
    private static List<LinkedHashMap<String, Object>> getLinkedHashMaps(List<LinkedHashMap<String, Object>> resultList, List<LinkedHashMap<String, Object>> parentTotalList) {
        for (LinkedHashMap<String, Object> stringObjectLinkedHashMap : parentTotalList) {
            LinkedHashMap<String, Object> map = new LinkedHashMap<>();
            for (Entry<String, Object> entry : stringObjectLinkedHashMap.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (key.equals(ID_STR)) {
                    List<LinkedHashMap<String, Object>> data = queryRecursiveChildrenList(String.valueOf(value));
                    if (!data.isEmpty()) {
                        map.put("children", data);
                    }
                }
                map.put(key, value);
            }
            resultList.add(map);
        }
        return resultList;
    }

    /**
     * 设置初始化参数
     *
     * @param totalList 原始列表
     */
    private static void setInitParams(List<LinkedHashMap<String, Object>> totalList) {
        PARENT_ID = INIT_PARENT;
        ID_STR = INIT_ID;
        setTotalList(totalList);
    }
}
